package com.smap.layer;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author Shen
 * 
 */
public abstract class GridLayer extends CanvasLayer {

	double minX;
	double minY;

	List<Tile> tiles = new ArrayList<Tile>();
	int tileSize = 256;

	public void draw() {
		clearScreen();
		// Calculate tiles based on resolution, tileSize and map max extent
		caculateTiles();
		drawTiles();
	}

	private void drawTiles() {
		for (Tile tile : tiles) {
			setUrl(tile);
			drawPicture(tile.imageUrl, tile.offsetX + (this.width / 2),
					tile.offsetY + (this.height / 2));
		}
	}

	public abstract void setUrl(Tile tile);

	private void caculateTiles() {
		tiles.clear();
		double res = map.getResolution();
		// get centre pixel
		int px = (int) Math.round((map.getCentre().x + minX) / res);
		int py = (int) Math.round((map.getCentre().y + minY) / res);
		Tile cTile = new Tile();
		cTile.z = map.getZoom();
		cTile.x = (int) Math.ceil(px / ((double) tileSize) - 1);
		cTile.y = (int) Math.ceil(py / ((double) tileSize) - 1);
		cTile.offsetX = -(px - cTile.x * tileSize);
		cTile.offsetY = (py - cTile.y * tileSize) - tileSize;

		int xRange = 1 + (this.width / 2) / tileSize;
		int yRange = 1 + (this.height / 2) / tileSize;

		// xRange = yRange = 0;

		for (int i = 0; i <= xRange; i++)
			for (int j = 0; j <= yRange; j++) {
				tiles.add(cTile.clone(i, j, tileSize));
				if (i != 0 && j != 0) {
					tiles.add(cTile.clone(-i, -j, tileSize));
				}
				if (i != 0) {
					tiles.add(cTile.clone(-i, j, tileSize));
				}
				if (j != 0) {
					tiles.add(cTile.clone(i, -j, tileSize));
				}
			}
		// System.out.println(xRange + "," + yRange + "=" + tiles.size());
	}

	public static class Tile {
		public int offsetX;
		public int offsetY;
		public int x;
		public int y;
		public int z;

		public String imageUrl;
		public String bbox;

		public Tile clone(int x, int y, int tileSize) {
			Tile newTile = new Tile();
			newTile.z = this.z;
			newTile.x = this.x + x;
			newTile.y = this.y + y;
			newTile.offsetX = this.offsetX + x * tileSize;
			newTile.offsetY = this.offsetY - y * tileSize;
			return newTile;
		}

		@Override
		public String toString() {
			return "Tile [x=" + x + ", y=" + y + ", z=" + z + ", imageUrl="
					+ imageUrl + "]";
		}

	}

}
